package multi_thread.basic;

import java.time.Duration;
import java.time.LocalDateTime;

/**
 * @author Cheng Jun
 * Description: interrupted方法是类方法，它用来获取当前线程的中断标志符，然后将中断标识符重置为 false
 * interrupt()方法是实例方法，无返回值，将线程的中断标识符设置为 true
 * isInterrupted 方法实例方法，返回线程的中断标识符
 * @version 1.0
 * @date 2020/3/1 13:50
 */
public class InterruptedExample {

    public static void main(String[] args) throws Exception {

        Thread thread = new Thread(() -> {
            Thread.currentThread().interrupt();
            System.out.println(Thread.currentThread().getName() + "线程的中断标记符为" + Thread.currentThread().isInterrupted());
            // interrupted 是类方法，注意该方法返回 中断标志的同时，重置了中断标识为false，源码注释 说的是 cleared 清除，我觉得重置更准确。
            System.out.println(Thread.currentThread().getName() + "线程的中断标记符为" + Thread.interrupted());
            System.out.println(Thread.currentThread().getName() + "线程的中断标记符为" + Thread.currentThread().isInterrupted());
        });

        thread.start();

        // 中断 main 线程，后面代码照样运行。说明线程的 interrupt() 不中断 调用者的线程。
        // 从源码注释可以看到 有 三种情况 If this thread is blocked，后面两种情况不熟悉，也跟多线程的其它方法没太大关系。所以我只看第一种
        // 主要针对 wait join sleep 方法
        Thread.currentThread().interrupt();
        System.out.println(Thread.currentThread().getName() + "线程的中断标记符为" + Thread.interrupted());
        System.out.println(Thread.currentThread().getName() + "线程的中断标记符为" + Thread.currentThread().isInterrupted());

        Object lock = new Object();
        Thread thread1 = new Thread(() -> {
            LocalDateTime startDateTime = LocalDateTime.now();
            synchronized (lock) {
                try {
                    lock.wait(10_000);
                    System.out.println(Thread.currentThread() + "正常运行了 " + Duration.between(startDateTime, LocalDateTime.now()));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    System.out.println(Thread.currentThread() + "异常运行了" + Duration.between(startDateTime, LocalDateTime.now()));
                }
            }
        });
        thread1.start();
        Thread.sleep(2_000);
        //If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class,
        // or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class,
        // then its interrupt status will be cleared and it will receive an InterruptedException.
        //如果没有以上情况，interrupt 不会中断线程，需要开发者自己根据Thread.currentThread().isInterrupted()，获取中断标识符，从而实现中断逻辑。
        thread1.interrupt();
    }
}
